﻿//-----------------------------------------------------------------------
// <copyright file="Shadow.cs" company="Noboru Project">
//      Copyright (c) Noboru Project. All rights reserved.
//
//      This source code is subject to terms and conditions of the New BSD License (BSD).
//      A copy of the license can be found in the License.html file at the root of this 
//      distribution. If you can not locate the New BSD License (BSD), please send an 
//      email to noboru_adm@live.com.
//      By using this source code in any fashion, you are agreeing to be bound by
//      the terms of the New BSD License (BSD) for Noboru.
//
//      You must not remove this notice, or any other, from this software.
// </copyright>
//-----------------------------------------------------------------------

using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Noboru.Windows.Controls
{
    /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.Class"]/*' />
    [TemplatePart(Name = "BackgroundPart", Type = typeof(Canvas))]
    [TemplatePart(Name = "LayoutPart", Type = typeof(Grid))]
    [TemplatePart(Name = "RectangleTopLeftPart", Type = typeof(Rectangle))]
    [TemplatePart(Name = "RectangleTopPart", Type = typeof(Rectangle))]
    [TemplatePart(Name = "RectangleTopRightPart", Type = typeof(Rectangle))]
    [TemplatePart(Name = "RectangleMiddleRightPart", Type = typeof(Rectangle))]
    [TemplatePart(Name = "RectangleBottomRightPart", Type = typeof(Rectangle))]
    [TemplatePart(Name = "RectangleBottomPart", Type = typeof(Rectangle))]
    [TemplatePart(Name = "RectangleBottomLeftPart", Type = typeof(Rectangle))]
    [TemplatePart(Name = "RectangleMiddleLeftPart", Type = typeof(Rectangle))]
    [TemplatePart(Name = "RectangleMiddlePart", Type = typeof(Rectangle))]
    public class Shadow : ContentControl
    {
        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.AngleProperty"]/*' />
        public static readonly DependencyProperty AngleProperty = DependencyProperty.Register("Angle", typeof(double), typeof(Shadow), new PropertyMetadata(0.0, Shadow.PropertyChangedCallback));

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.CornerRadiusProperty"]/*' />
        public static readonly DependencyProperty CornerRadiusProperty = DependencyProperty.Register("CornerRadius", typeof(System.Windows.CornerRadius), typeof(Shadow), new PropertyMetadata(new System.Windows.CornerRadius(0), Shadow.PropertyChangedCallback));

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.DistanceProperty"]/*' />
        public static readonly DependencyProperty DistanceProperty = DependencyProperty.Register("Distance", typeof(double), typeof(Shadow), new PropertyMetadata(0.0, Shadow.PropertyChangedCallback));

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.ShadowColorProperty"]/*' />
        public static readonly DependencyProperty ShadowColorProperty = DependencyProperty.Register("ShadowColor", typeof(Color), typeof(Shadow), new PropertyMetadata(Colors.Transparent, Shadow.PropertyChangedCallback));

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.ShadowOpacityProperty"]/*' />
        public static readonly DependencyProperty ShadowOpacityProperty = DependencyProperty.Register("ShadowOpacity", typeof(double), typeof(Shadow), new PropertyMetadata(0.8, Shadow.PropertyChangedCallback));

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.ShadowWidthProperty"]/*' />
        public static readonly DependencyProperty ShadowWidthProperty = DependencyProperty.Register("ShadowWidth", typeof(double), typeof(Shadow), new PropertyMetadata(0.0, Shadow.PropertyChangedCallback));

        private double _gradientBaseWidth = 0.0;
        private double _gradientBaseHeight = 0.0;
        private Canvas _backgroundPart;
        private Grid _layoutPart;
        private Rectangle _rectangleTopLeftPart;
        private Rectangle _rectangleTopPart;
        private Rectangle _rectangleTopRightPart;
        private Rectangle _rectangleMiddleRightPart;
        private Rectangle _rectangleBottomRightPart;
        private Rectangle _rectangleBottomPart;
        private Rectangle _rectangleBottomLeftPart;
        private Rectangle _rectangleMiddleLeftPart;
        private Rectangle _rectangleMiddlePart;

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.Constructor"]/*' />
        public Shadow()
        {
            this.DefaultStyleKey = typeof(Shadow);
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.Angle"]/*' />
        public double Angle
        {
            get
            {
                return (double)this.GetValue(AngleProperty);
            }

            set
            {
                this.SetValue(AngleProperty, value);
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.CornerRadius"]/*' />
        public CornerRadius CornerRadius
        {
            get
            {
                return (System.Windows.CornerRadius)this.GetValue(CornerRadiusProperty);
            }

            set
            {
                this.SetValue(CornerRadiusProperty, value);
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.Distance"]/*' />
        public double Distance
        {
            get
            {
                return (double)this.GetValue(DistanceProperty);
            }

            set
            {
                this.SetValue(DistanceProperty, value);
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.ShadowColor"]/*' />
        public Color ShadowColor
        {
            get
            {
                return (Color)this.GetValue(ShadowColorProperty);
            }

            set
            {
                this.SetValue(ShadowColorProperty, value);
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.ShadowOpacity"]/*' />
        public double ShadowOpacity
        {
            get
            {
                return (double)this.GetValue(ShadowOpacityProperty);
            }

            set
            {
                this.SetValue(ShadowOpacityProperty, value);
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.ShadowWidth"]/*' />
        public double ShadowWidth
        {
            get
            {
                return (double)this.GetValue(ShadowWidthProperty);
            }

            set
            {
                this.SetValue(ShadowWidthProperty, value);
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.BackgroundPart"]/*' />
        protected Canvas BackgroundPart
        {
            get
            {
                return this._backgroundPart;
            }

            set
            {
                this._backgroundPart = value;
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.LayoutPart"]/*' />
        protected Grid LayoutPart
        {
            get 
            { 
                return this._layoutPart;
            }

            set 
            { 
                this._layoutPart = value;
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.RectangleTopLeftPart"]/*' />
        protected Rectangle RectangleTopLeftPart
        {
            get 
            { 
                return this._rectangleTopLeftPart;
            }

            set 
            { 
                this._rectangleTopLeftPart = value;
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.RectangleTopPart"]/*' />
        protected Rectangle RectangleTopPart
        {
            get 
            { 
                return this._rectangleTopPart;
            }

            set 
            { 
                this._rectangleTopPart = value;
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.RectangleTopRightPart"]/*' />
        protected Rectangle RectangleTopRightPart
        {
            get
            {
                return this._rectangleTopRightPart;
            }

            set
            {
                this._rectangleTopRightPart = value;
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.RectangleMiddleRightPart"]/*' />
        protected Rectangle RectangleMiddleRightPart
        {
            get
            {
                return this._rectangleMiddleRightPart;
            }

            set
            {
                this._rectangleMiddleRightPart = value;
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.RectangleBottomRightPart"]/*' />
        protected Rectangle RectangleBottomRightPart
        {
            get
            {
                return this._rectangleBottomRightPart;
            }

            set
            {
                this._rectangleBottomRightPart = value;
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.RectangleBottomPart"]/*' />
        protected Rectangle RectangleBottomPart
        {
            get
            {
                return this._rectangleBottomPart;
            }

            set
            {
                this._rectangleBottomPart = value;
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.RectangleBottomLeftPart"]/*' />
        protected Rectangle RectangleBottomLeftPart
        {
            get
            {
                return this._rectangleBottomLeftPart;
            }

            set
            {
                this._rectangleBottomLeftPart = value;
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.RectangleMiddleLeftPart"]/*' />
        protected Rectangle RectangleMiddleLeftPart
        {
            get
            {
                return this._rectangleMiddleLeftPart;
            }

            set
            {
                this._rectangleMiddleLeftPart = value;
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.RectangleMiddlePart"]/*' />
        protected Rectangle RectangleMiddlePart
        {
            get
            {
                return this._rectangleMiddlePart;
            }

            set
            {
                this._rectangleMiddlePart = value;
            }
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.OnApplyTemplate"]/*' />
        public override void OnApplyTemplate()
        {
            base.OnApplyTemplate();

            this.BackgroundPart = (Canvas)GetTemplateChild("BackgroundPart");
            this.LayoutPart = (Grid)GetTemplateChild("LayoutPart");
            this.RectangleTopLeftPart = (Rectangle)GetTemplateChild("RectangleTopLeftPart");
            this.RectangleTopPart = (Rectangle)GetTemplateChild("RectangleTopPart");
            this.RectangleTopRightPart = (Rectangle)GetTemplateChild("RectangleTopRightPart");
            this.RectangleMiddleRightPart = (Rectangle)GetTemplateChild("RectangleMiddleRightPart");
            this.RectangleBottomRightPart = (Rectangle)GetTemplateChild("RectangleBottomRightPart");
            this.RectangleBottomPart = (Rectangle)GetTemplateChild("RectangleBottomPart");
            this.RectangleBottomLeftPart = (Rectangle)GetTemplateChild("RectangleBottomLeftPart");
            this.RectangleMiddleLeftPart = (Rectangle)GetTemplateChild("RectangleMiddleLeftPart");
            this.RectangleMiddlePart = (Rectangle)GetTemplateChild("RectangleMiddlePart");
        }

        /// <include file='Documentation\ShadowDocumentation.uex' path='Members/Member[@for="Shadow.OnContentChanged"]/*' />
        protected override void OnContentChanged(object oldContent, object newContent)
        {
            base.OnContentChanged(oldContent, newContent);

            if (oldContent != null)
            {
                ((FrameworkElement)oldContent).SizeChanged -= new SizeChangedEventHandler(this.Shadow_SizeChanged);
            }

            FrameworkElement content = newContent as FrameworkElement;
            if (content != null)
            {
                content.SizeChanged += new SizeChangedEventHandler(this.Shadow_SizeChanged);

                if (this.Content is Border)
                {
                    CornerRadius cornerRadius = (CornerRadius)content.GetValue(Border.CornerRadiusProperty);
                    this.CornerRadius = cornerRadius;
                }

                this.Visibility = content.Visibility;
            }

            this.LayoutGradient();
        }

        private static void PropertyChangedCallback(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ((Shadow)sender).OnPropertyChanged(e);
        }

        private void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            this.LayoutGradient();
        }

        private void Shadow_SizeChanged(object sender, SizeChangedEventArgs e)
        {
            if (this.Content != null)
            {
                FrameworkElement content = (FrameworkElement)this.Content;
                this._gradientBaseHeight = content.ActualHeight;
                this._gradientBaseWidth = content.ActualWidth;

                this.Visibility = content.Visibility;
            }
            else
            {
                this._gradientBaseHeight = this.Height;
                this._gradientBaseWidth = this.Width;
            }

            this.LayoutGradient();
        }

        private void LayoutGradient()
        {
            if (this._layoutPart != null)
            {
                double roundAmount = Math.Round(this.CornerRadius.TopLeft);
                double gradientWidth = Math.Round(this.ShadowWidth);

                if (roundAmount > this._gradientBaseHeight / 2.0)
                {
                    roundAmount = Math.Round(this._gradientBaseHeight / 2.0);
                }

                if (roundAmount > this._gradientBaseWidth / 2.0)
                {
                    roundAmount = Math.Round(this._gradientBaseWidth / 2.0);
                }

                FrameworkElement content = (FrameworkElement)this.Content;
                if (content != null)
                {
                    this._layoutPart.SetValue(Canvas.ZIndexProperty, (int)content.GetValue(Canvas.ZIndexProperty) - 1);
                    this._layoutPart.Clip = null;
                }

                double totalWidth = gradientWidth + roundAmount;

                GridLength edgeLength = new GridLength((double)totalWidth, GridUnitType.Pixel);
                GridLength gridCenterHeight;
                GridLength gridCenterWidth;

                this.CreateGradients(gradientWidth, roundAmount);

                gridCenterHeight = new GridLength(this._gradientBaseHeight - totalWidth - roundAmount, GridUnitType.Pixel);
                gridCenterWidth = new GridLength(this._gradientBaseWidth - totalWidth - roundAmount, GridUnitType.Pixel);
                if (gridCenterHeight.Value < 0)
                {
                    gridCenterHeight = new GridLength(0, GridUnitType.Pixel);
                }

                if (gridCenterWidth.Value < 0)
                {
                    gridCenterWidth = new GridLength(0, GridUnitType.Pixel);
                }

                this._layoutPart.Width = gridCenterWidth.Value + (2.0 * totalWidth);
                this._layoutPart.Height = gridCenterHeight.Value + (2.0 * totalWidth);

                TranslateTransform translateTransform = new TranslateTransform();
                translateTransform.X = Math.Round((this.Distance * Math.Cos((this.Angle * Math.PI) / -180.0)) + (this._gradientBaseWidth - gridCenterWidth.Value - 2.0 * edgeLength.Value) / 2.0);
                translateTransform.Y = Math.Round((this.Distance * Math.Sin((this.Angle * Math.PI) / -180.0)) + (this._gradientBaseHeight - gridCenterHeight.Value - 2.0 * edgeLength.Value) / 2.0);
                TransformGroup transformGroup = new TransformGroup();
                transformGroup.Children.Add(translateTransform);

                this._layoutPart.RenderTransform = transformGroup;

                this._layoutPart.ColumnDefinitions[1].Width = gridCenterWidth;
                this._layoutPart.RowDefinitions[1].Height = gridCenterHeight;
                this._layoutPart.ColumnDefinitions[0].Width = edgeLength;
                this._layoutPart.ColumnDefinitions[2].Width = edgeLength;
                this._layoutPart.RowDefinitions[0].Height = edgeLength;
                this._layoutPart.RowDefinitions[2].Height = edgeLength;
            }
        }

        private void CreateGradients(double width, double roundAmount)
        {
            LinearGradientBrush linearGradientBrush;
            GradientStop gradientStop;
            RadialGradientBrush radialGradientBrush;

            TransformGroup transformGroup;
            ScaleTransform scaleTransform;
            SkewTransform skewTransform;
            RotateTransform rotateTransform;
            TranslateTransform translateTransform;

            double roundingOffset = (width > 0) ? roundAmount / (width + roundAmount) : 0.999;

            Color startColor = Color.FromArgb(0x00, this.ShadowColor.R, this.ShadowColor.G, this.ShadowColor.B);

            Color endColor;

            if (this.ShadowOpacity < 1.0)
            {
                endColor = Color.FromArgb(this.ShadowColor.A, this.ShadowColor.R, this.ShadowColor.G, this.ShadowColor.B);
                endColor.A = (byte)(255 * this.ShadowOpacity);
            }
            else
            {
                endColor = Color.FromArgb(this.ShadowColor.A, this.ShadowColor.R, this.ShadowColor.G, this.ShadowColor.B);
            }

            radialGradientBrush = new RadialGradientBrush();            
            gradientStop = new GradientStop();

            gradientStop.Color = startColor;
            gradientStop.Offset = 1.0;
            radialGradientBrush.GradientStops.Add(gradientStop);
            gradientStop = new GradientStop();
            gradientStop.Color = endColor;
            gradientStop.Offset = roundingOffset;
            radialGradientBrush.GradientStops.Add(gradientStop);
            
            transformGroup = new TransformGroup();
            scaleTransform = new ScaleTransform();
            scaleTransform.CenterX = 0.5; 
            scaleTransform.CenterY = 0.5; 
            scaleTransform.ScaleX = 2; 
            scaleTransform.ScaleY = 2;
            transformGroup.Children.Add(scaleTransform);

            skewTransform = new SkewTransform();
            skewTransform.CenterX = 0.5;
            skewTransform.CenterY = 0.5;
            transformGroup.Children.Add(skewTransform);
            rotateTransform = new RotateTransform();
            rotateTransform.CenterX = 0.5;
            rotateTransform.CenterY = 0.5;
            transformGroup.Children.Add(rotateTransform);
            translateTransform = new TranslateTransform();
            translateTransform.X = 0.5;
            translateTransform.Y = 0.5;
            transformGroup.Children.Add(translateTransform);
            radialGradientBrush.RelativeTransform = transformGroup;
            
            this._rectangleTopLeftPart.Fill = radialGradientBrush;
            this._rectangleTopLeftPart.StrokeThickness = 0;

            linearGradientBrush = new LinearGradientBrush();

            linearGradientBrush.StartPoint = new Point(0.5, 0.0);
            linearGradientBrush.EndPoint = new Point(0.5, 1.0);
            gradientStop = new GradientStop();
            gradientStop.Color = startColor;
            gradientStop.Offset = 0;
            linearGradientBrush.GradientStops.Add(gradientStop);
            gradientStop = new GradientStop();
            gradientStop.Color = endColor;
            gradientStop.Offset = 1.0 - roundingOffset;
            linearGradientBrush.GradientStops.Add(gradientStop);
            
            this._rectangleTopPart.Fill = linearGradientBrush;

            radialGradientBrush = new RadialGradientBrush();

            gradientStop = new GradientStop();
            gradientStop.Color = startColor;
            gradientStop.Offset = 1.0;
            radialGradientBrush.GradientStops.Add(gradientStop);
            gradientStop = new GradientStop();
            gradientStop.Color = endColor;
            gradientStop.Offset = roundingOffset;
            radialGradientBrush.GradientStops.Add(gradientStop);
            transformGroup = new TransformGroup();
            scaleTransform = new ScaleTransform();
            scaleTransform.CenterX = 0.5; 
            scaleTransform.CenterY = 0.5; 
            scaleTransform.ScaleX = 2; 
            scaleTransform.ScaleY = 2;
            transformGroup.Children.Add(scaleTransform);
            skewTransform = new SkewTransform();
            skewTransform.CenterX = 0.5; 
            skewTransform.CenterY = 0.5;
            transformGroup.Children.Add(skewTransform);
            rotateTransform = new RotateTransform();
            rotateTransform.CenterX = 0.5; 
            rotateTransform.CenterY = 0.5;
            transformGroup.Children.Add(rotateTransform);
            translateTransform = new TranslateTransform();
            translateTransform.X = -0.5; 
            translateTransform.Y = 0.5;
            transformGroup.Children.Add(translateTransform);
            radialGradientBrush.RelativeTransform = transformGroup;
           
            this._rectangleTopRightPart.Fill = radialGradientBrush;
            this._rectangleTopRightPart.StrokeThickness = 0;

            linearGradientBrush = new LinearGradientBrush();

            linearGradientBrush.StartPoint = new Point(1.0, 0.5);
            linearGradientBrush.EndPoint = new Point(0.0, 0.5);
            gradientStop = new GradientStop();
            gradientStop.Color = startColor;
            gradientStop.Offset = 1.0;
            linearGradientBrush.GradientStops.Add(gradientStop);
            gradientStop = new GradientStop();
            gradientStop.Color = endColor;
            gradientStop.Offset = roundingOffset;
            linearGradientBrush.GradientStops.Add(gradientStop);
            
            this._rectangleMiddleLeftPart.Fill = linearGradientBrush;

            SolidColorBrush s = new SolidColorBrush(endColor);
            this._rectangleMiddlePart.Fill = s;

            linearGradientBrush = new LinearGradientBrush();

            linearGradientBrush.StartPoint = new Point(1.0, 0.5);
            linearGradientBrush.EndPoint = new Point(0.0, 0.5);
            gradientStop = new GradientStop();
            gradientStop.Color = startColor;
            gradientStop.Offset = 0.0;
            linearGradientBrush.GradientStops.Add(gradientStop);
            gradientStop = new GradientStop();
            gradientStop.Color = endColor;
            gradientStop.Offset = 1.0 - roundingOffset;
            linearGradientBrush.GradientStops.Add(gradientStop);
            
            this._rectangleMiddleRightPart.Fill = linearGradientBrush;

            radialGradientBrush = new RadialGradientBrush();
            
            gradientStop = new GradientStop();
            gradientStop.Color = startColor;
            gradientStop.Offset = 1.0;
            radialGradientBrush.GradientStops.Add(gradientStop);
            gradientStop = new GradientStop();
            gradientStop.Color = endColor;
            gradientStop.Offset = roundingOffset;
            radialGradientBrush.GradientStops.Add(gradientStop);
            transformGroup = new TransformGroup();
            scaleTransform = new ScaleTransform();
            scaleTransform.CenterX = 0.5; 
            scaleTransform.CenterY = 0.5; 
            scaleTransform.ScaleX = 2; 
            scaleTransform.ScaleY = 2;
            transformGroup.Children.Add(scaleTransform);
            skewTransform = new SkewTransform();
            skewTransform.CenterX = 0.5; 
            skewTransform.CenterY = 0.5;
            transformGroup.Children.Add(skewTransform);
            rotateTransform = new RotateTransform();
            rotateTransform.CenterX = 0.5; 
            rotateTransform.CenterY = 0.5;
            transformGroup.Children.Add(rotateTransform);
            translateTransform = new TranslateTransform();
            translateTransform.X = 0.5; 
            translateTransform.Y = -0.5;
            transformGroup.Children.Add(translateTransform);
            radialGradientBrush.RelativeTransform = transformGroup;
            
            this._rectangleBottomLeftPart.Fill = radialGradientBrush;
            this._rectangleBottomLeftPart.StrokeThickness = 0;

            linearGradientBrush = new LinearGradientBrush();
            
            linearGradientBrush.StartPoint = new Point(0.5, 0.0);
            linearGradientBrush.EndPoint = new Point(0.5, 1.0);
            gradientStop = new GradientStop();
            gradientStop.Color = startColor;
            gradientStop.Offset = 1.0;
            linearGradientBrush.GradientStops.Add(gradientStop);
            gradientStop = new GradientStop();
            gradientStop.Color = endColor;
            gradientStop.Offset = roundingOffset;
            linearGradientBrush.GradientStops.Add(gradientStop);
            
            this._rectangleBottomPart.Fill = linearGradientBrush;

            radialGradientBrush = new RadialGradientBrush();
           
            gradientStop = new GradientStop();
            gradientStop.Color = startColor;
            gradientStop.Offset = 1.0;
            radialGradientBrush.GradientStops.Add(gradientStop);
            gradientStop = new GradientStop();
            gradientStop.Color = endColor;
            gradientStop.Offset = roundingOffset;
            radialGradientBrush.GradientStops.Add(gradientStop);
            transformGroup = new TransformGroup();
            scaleTransform = new ScaleTransform();
            scaleTransform.CenterX = 0.5; 
            scaleTransform.CenterY = 0.5; 
            scaleTransform.ScaleX = 2; 
            scaleTransform.ScaleY = 2;
            transformGroup.Children.Add(scaleTransform);
            skewTransform = new SkewTransform();
            skewTransform.CenterX = 0.5;
            skewTransform.CenterY = 0.5;
            transformGroup.Children.Add(skewTransform);
            rotateTransform = new RotateTransform();
            rotateTransform.CenterX = 0.5;
            rotateTransform.CenterY = 0.5;
            transformGroup.Children.Add(rotateTransform);
            translateTransform = new TranslateTransform();
            translateTransform.X = -0.5; 
            translateTransform.Y = -0.5;
            transformGroup.Children.Add(translateTransform);
            radialGradientBrush.RelativeTransform = transformGroup;
            
            this._rectangleBottomRightPart.Fill = radialGradientBrush;
            this._rectangleBottomRightPart.StrokeThickness = 0;
        }
    }
}
